﻿
package extremefx.i18n {
	/**
	 * @author Marcelo Volmaro
	 */
	public final class TextInfo {
		private var _culture:Culture;
		private var _dotI:Boolean = false;
		
		public function TextInfo(pCult:Culture) {
			_culture = pCult;
			switch (pCult.twoLetterISOCountryName){
				case "ar":
				case "tr":
					_dotI = true;
			}
		}
		
		public function isLeftToRight():Boolean {
			switch (_culture.twoLetterISOCountryName){
				case "ar":
				case "he":
				case "ur":
				case "fa":
				case "syr":
				case "div":
					return true;
			}
			
			return false;
		}
		
		public function toLower(pString:String):String {
			var a:Array = pString.split("");
			var idx:uint = 0;
			var char:String;
			
			while (char = a[idx]) a[idx++] = toLowerChar(char);
			return a.join("");
		}
		
		public function toUpper(pString:String):String {
			var a:Array = pString.split("");
			var idx:uint = 0;
			var char:String;
			
			while (char = a[idx]) a[idx++] = toUpperChar(char);
			return a.join("");
		}
		
//		public function toTitleCase(pString:String):String {
//			var sb:StringBuilder;
//			var i:uint = 0;
//			var start:uint = 0;
//			var len:uint = pString.length;
//			
//			while (i < len) {
//				if (!Char.isLetter (pString[i++]))
//					continue;
//				i--;
//				var t:String = toTitleCaseChar(pString[i]);
//				var capitalize:Boolean = true;
//				
//				if (t == pString[i]) {
//					capitalize = false;
//					var allTitle:Boolean = true;
//					// if the word is all titlecase,
//					// then don't capitalize it.
//					var saved:uint = i;
//					
//					while (++i < len) {
//						if (Char.isWhiteSpace (pString[i])) break;
//						
//						t = toTitleCaseChar(pString[i]);
//						if (t != pString[i]) {
//							allTitle = false;
//							break;
//						}
//					}
//					
//					if (allTitle) continue;
//					i = saved;
//
//					// still check if all remaining
//					// characters are lowercase,
//					// where we don't have to modify
//					// the source word.
//					while (++i < len) {
//						if (Char.isWhiteSpace (pString[i])) break;
//						
//						if (toLowerChar(pString[i]) != pString[i]) {
//							capitalize = true;
//							i = saved;
//							break;
//						}
//					}
//				}
//
//				if (capitalize) {
//					if (sb == null) sb = new StringBuilder();
//					sb.append (pString, start, i - start);
//					sb.append (toTitleCaseChar(pString[i]));
//					start = i + 1;
//					
//					while (++i < len) {
//						if (Char.isWhiteSpace (pString[i])) break;
//						
//						sb.append (toLowerChar(pString[i]));
//					}
//					start = i;
//				}
//			}
//			
//			if (sb != null) sb.append (pString, start, len - start);
//			return sb != null ? sb.toString() : pString;
//		}
//		
//		private function toTitleCaseChar(pChar:String):String {
//			// Handle some Latin characters.
//			switch (pChar) {
//			case '\u01c4':
//			case '\u01c5':
//			case '\u01c6':
//				return '\u01c5';
//				
//			case '\u01c7':
//			case '\u01c8':
//			case '\u01c9':
//				return '\u01c8';
//				
//			case '\u01ca':
//			case '\u01cb':
//			case '\u01cc':
//				return '\u01cb';
//				
//			case '\u01f1':
//			case '\u01f2':
//			case '\u01f3':
//				return '\u01f2';
//			}
//			
//			if ('\u2170' <= pChar && pChar <= '\u217f' || // Roman numbers
//				'\u24d0' <= pChar && pChar <= '\u24e9')
//				return pChar;
//
//			return toUpperChar(pChar);
//		}
		
		private function toLowerChar(pChar:String):String {
			if (pChar < "A" || "`" < pChar && pChar < " ") {
				return pChar;
				
			} else if ("@" < pChar && pChar < '[' && (!_dotI || pChar != 'I')){
				return pChar.toLowerCase();
			}
			
			if (_culture.id == 0x7F) return pChar.toLowerCase();

			switch (pChar) {
			case 'I': // Latin uppercase I
				if (_dotI) return '\u0131'; // I becomes dotless i
			break;
			
			case '\u0130': // I-dotted
				return '\u0069'; // i

			case '\u01c5': // LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON
				return '\u01c6';
				
			// \u01c7 -> \u01c9 (LJ) : invariant
			case '\u01c8': // LATIN CAPITAL LETTER L WITH SMALL LETTER J
				return '\u01c9';
				
			// \u01ca -> \u01cc (NJ) : invariant
			case '\u01cb': // LATIN CAPITAL LETTER N WITH SMALL LETTER J
				return '\u01cc';
				
			// WITH CARON : invariant
			// WITH DIAERESIS AND * : invariant

			case '\u01f2': // LATIN CAPITAL LETTER D WITH SMALL LETTER Z
				return '\u01f3';
				
			case '\u03d2':  // ? it is not in ICU
				return '\u03c5';
				
			case '\u03d3':  // ? it is not in ICU
				return '\u03cd';
				
			case '\u03d4':  // ? it is not in ICU
				return '\u03cb';
			}
			
			return pChar.toLowerCase();
		}
		
		private function toUpperChar(pChar:String):String {
			if (pChar < "`") {
				return pChar;
				
			} else if ("`" < pChar && pChar < '{' && (!_dotI || pChar != 'i')){
				return pChar.toUpperCase();
			}
			
			if (_culture.id == 0x7F) return pChar.toUpperCase();

			switch (pChar) {
			case 'i': // Latin lowercase i
				if (_dotI) return '\u0130'; // dotted capital I
			break;
			
			case '\u0131': // dotless i
				return '\u0049'; // I

			case '\u01c5': // see toLower()
				return '\u01c4';
				
			case '\u01c8': // see toLower()
				return '\u01c7';
				
			case '\u01cb': // see toLower()
				return '\u01ca';
				
			case '\u01f2': // see toLower()
				return '\u01f1';
				
			case '\u0390': // GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
				return '\u03aa'; // it is not in ICU
				
			case '\u03b0': // GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
				return '\u03ab'; // it is not in ICU
				
			case '\u03d0': // GREEK BETA
				return '\u0392';
				
			case '\u03d1': // GREEK THETA
				return '\u0398';
				
			case '\u03d5': // GREEK PHI
				return '\u03a6';
				
			case '\u03d6': // GREEK PI
				return '\u03a0';
				
			case '\u03f0': // GREEK KAPPA
				return '\u039a';
				
			case '\u03f1': // GREEK RHO
				return '\u03a1';
			}
			
			return pChar.toUpperCase();
		}
	}
}
